package com.android.toast

import android.R
import android.app.Activity
import android.content.Context
import android.content.pm.ActivityInfo
import android.graphics.PixelFormat
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.opengl.Visibility
import android.os.*
import android.view.*
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import java.lang.IllegalArgumentException

/**
 * @Author LuoKun
 * @Des
 */
class AndroidToast<A : AndroidToast<A>> : Runnable {

    companion object {
        private val HANDLER: Handler = Handler(Looper.getMainLooper())
    }

    /**上下文*/
    private var mContext: Context? = null

    /**根布局*/
    private var mDecorView: ViewGroup? = null

    /**当前是否已显示*/
    private var mShowing: Boolean = false

    /**悬浮窗口*/
    private var mWindowManager: WindowManager? = null

    /**窗口参数*/
    private var mWindowParams: WindowManager.LayoutParams? = null

    /**窗口显示时长*/
    private var mDuration: Int = 0

    /**Toast 生命周期管理*/
    private var mLifecycle: ActivityLifecycle? = null

    /**Toast显示和取消监听*/
    private var mListener: OnLifecycle? = null

    constructor(context: Context) {
        this.mContext = context
        mDecorView = WindowLayout(context)
        mWindowManager = (context.getSystemService(Context.WINDOW_SERVICE)) as WindowManager
        //配置一些默认的参数
        mWindowParams = WindowManager.LayoutParams()
        mWindowParams?.height = WindowManager.LayoutParams.WRAP_CONTENT
        mWindowParams?.width = WindowManager.LayoutParams.WRAP_CONTENT
        mWindowParams?.format = PixelFormat.TRANSLUCENT
        mWindowParams?.windowAnimations = R.style.Animation_Toast
        mWindowParams?.packageName = context.packageName
        // 设置触摸外层布局（除 WindowManager 外的布局，默认是 WindowManager 显示的时候外层不可触摸）
        // 需要注意的是设置了 FLAG_NOT_TOUCH_MODAL 必须要设置 FLAG_NOT_FOCUSABLE，否则就会导致用户按返回键无效
        mWindowParams?.flags = (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
    }


    /**设置宽度*/
    fun setWidth(width: Int): A {
        mWindowParams?.width = width
        if ((mDecorView?.childCount ?: 0) > 0) {
            val contentView = mDecorView?.getChildAt(0)
            val layoutParams = contentView?.layoutParams
            if (layoutParams != null && layoutParams.width != width) {
                layoutParams.width = width
                contentView.layoutParams = layoutParams
            }
        }
        update()
        return this as A
    }

    /**设置高度*/
    fun setHeight(height: Int): A {
        mWindowParams?.height = height
        if ((mDecorView?.childCount ?: 0) > 0) {
            val contentView = mDecorView?.getChildAt(0)
            val layoutParams = contentView?.layoutParams
            if (layoutParams != null && layoutParams.height != height) {
                layoutParams.height = height
                contentView.layoutParams = layoutParams
            }
        }
        update()
        return this as A
    }

    /**设置窗口重心*/
    fun setGravity(gravity: Int): A {
        mWindowParams?.gravity = gravity
        update()
        return this as A
    }

    /**
     * 设置窗口方向
     *
     * 自适应：[ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED]
     * 横屏：[ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE]
     * 竖屏：[ActivityInfo.SCREEN_ORIENTATION_PORTRAIT]
     */
    fun setScreenOrientation(orientation: Int): A {
        mWindowParams?.screenOrientation = orientation
        update()
        return this as A
    }

    /**设置水平偏移量*/
    fun setXOffset(x: Int): A {
        mWindowParams?.x = x
        update()
        return this as A
    }

    /**设置垂直偏移量*/
    fun setYOffset(y: Int): A {
        mWindowParams?.y = y
        update()
        return this as A
    }

    /**是否外层可触摸*/
    fun setOutsideTouchable(touchable: Boolean): A {
        val flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
        if (touchable) {
            addWindowFlags(flags)
        } else {
            clearWindowFlags(flags)
        }
        update()
        return this as A
    }

    /**设置窗口背景阴影强度*/
    fun setBackgroundDimAmount(amount: Float): A {
        require(!(amount < 0 || amount > 1)) { "are you ok?" }
        mWindowParams?.dimAmount = amount
        val flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND
        if (amount != 0f) {
            addWindowFlags(flags)
        } else {
            clearWindowFlags(flags)
        }
        update()
        return this as A
    }

    /**是否有这个标志位*/
    fun hasWindowFlags(flags: Int): Boolean {
        return (mWindowParams?.flags ?: 0) and flags != 0
    }

    /**添加一个标记位*/
    fun addWindowFlags(flags: Int): A {
        mWindowParams?.flags = mWindowParams!!.flags or flags
        update()
        return this as A
    }

    /**移除一个标记位*/
    fun clearWindowFlags(flags: Int): A {
        mWindowParams?.flags = mWindowParams!!.flags and flags.inv()
        update()
        return this as A
    }

    /**设置标记位*/
    fun setWindowFlags(flags: Int): A {
        mWindowParams?.flags = flags
        update()
        return this as A
    }

    /**设置窗口类型*/
    fun setWindowType(type: Int): A {
        mWindowParams?.type = type
        update()
        return this as A
    }

    /**设置动画样式*/
    fun setAnimStyle(id: Int): A {
        mWindowParams?.windowAnimations = id
        update()
        return this as A
    }

    /**
     * 设置软键盘模式
     *
     * [WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED]：没有指定状态,系统会选择一个合适的状态或依赖于主题的设置
     * [WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED]：不会改变软键盘状态
     * [WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN]：当用户进入该窗口时，软键盘默认隐藏
     * [WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN]：当窗口获取焦点时，软键盘总是被隐藏
     * [WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE]：当软键盘弹出时，窗口会调整大小
     * [WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN]：当软键盘弹出时，窗口不需要调整大小，要确保输入焦点是可见的
     */
    fun setSoftInputMode(mode: Int): A {
        mWindowParams?.softInputMode = mode
        // 如果设置了不能触摸，则擦除这个标记，否则会导致无法弹出输入法
        clearWindowFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
        update()
        return this as A
    }

    /**设置窗口 Token*/
    fun setWindowToken(token: IBinder?): A {
        mWindowParams?.token = token
        update()
        return this as A
    }

    /**设置窗口透明度*/
    fun setWindowAlpha(alpha: Float): A {
        mWindowParams?.alpha = alpha
        update()
        return this as A
    }

    /**设置垂直间距*/
    fun setVerticalMargin(verticalMargin: Float): A {
        mWindowParams?.verticalMargin = verticalMargin
        update()
        return this as A
    }

    /**设置水平间距*/
    fun setHorizontalMargin(horizontalMargin: Float): A {
        mWindowParams?.horizontalMargin = horizontalMargin
        update()
        return this as A
    }

    /**设置位图格式*/
    fun setBitmapFormat(format: Int): A {
        mWindowParams?.format = format
        update()
        return this as A
    }

    /**设置状态栏的可见性*/
    fun setSystemUiVisibility(systemUiVisibility: Int): A {
        mWindowParams?.systemUiVisibility = systemUiVisibility
        update()
        return this as A
    }

    /**设置垂直权重*/
    fun setVerticalWeight(verticalWeight: Float): A {
        mWindowParams?.verticalWeight = verticalWeight
        update()
        return this as A
    }


    /**设置挖孔屏下的显示模式*/
    fun setLayoutInDisplayCutoutMode(mode: Int): A {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            mWindowParams?.layoutInDisplayCutoutMode = mode
            update()
        }
        return this as A
    }

    /**设置窗口在哪个显示屏上显示*/
    fun setPreferredDisplayModeId(id: Int): A {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mWindowParams?.preferredDisplayModeId = id
            update()
        }
        return this as A
    }

    /**设置窗口标题*/
    fun setWindowTitle(title: CharSequence): A {
        mWindowParams?.title = title
        update()
        return this as A
    }

    /**设置屏幕的亮度*/
    fun setScreenBrightness(screenBrightness: Float): A {
        mWindowParams?.screenBrightness = screenBrightness
        update()
        return this as A
    }

    /**设置按键的亮度*/
    fun setButtonBrightness(buttonBrightness: Float): A {
        mWindowParams?.buttonBrightness = buttonBrightness
        update()
        return this as A
    }

    /**设置窗口的刷新率*/
    fun setPreferredRefreshRate(preferredRefreshRate: Float): A {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mWindowParams?.preferredRefreshRate = preferredRefreshRate
            update()
        }
        return this as A
    }

    /**设置窗口的颜色模式*/
    fun setColorMode(colorMode: Int): A {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            mWindowParams?.colorMode = colorMode
            update()
        }
        return this as A
    }

    /**设置窗口高斯模糊半径大小（Android 12 才有的）*/
    fun setBlurBehindRadius(blurBehindRadius: Int): A {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            mWindowParams?.blurBehindRadius = blurBehindRadius
            addWindowFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND)
            update()
        }
        return this as A
    }

    /**重新设置 WindowManager 参数集*/
    fun setWindowParams(params: WindowManager.LayoutParams): A {
        mWindowParams = params
        update()
        return this as A
    }

    /**限定显示时长*/
    fun setDuration(duration: Int): A {
        mDuration = duration
        if (isShowing() && mDuration != 0) {
            removeCallbacks(this)
            postDelayed(this, mDuration.toLong())
        }
        return this as A
    }

    /**设置生命周期监听*/
    fun setOnToastLifecycle(listener: OnLifecycle): A {
        mListener = listener
        return this as A
    }

    /**设置根布局*/
    fun setDecorView(viewGroup: ViewGroup): A {
        mDecorView = viewGroup
        return this as A
    }

    /**设置内容布局*/
    fun setContentView(id: Int): A {
        return setContentView(LayoutInflater.from(mContext).inflate(id, mDecorView, false))
    }

    fun setContentView(view: View): A {
        if (mDecorView?.childCount == 0) {
            mDecorView?.removeAllViews()
        }
        mDecorView?.addView(view)
        val layoutParams = view.layoutParams
        if (layoutParams is ViewGroup.MarginLayoutParams) {
            var marginLayoutParams: ViewGroup.MarginLayoutParams = layoutParams
            //清除 Margin，因为 WindowManager 没有这一属性可以设置，并且会跟根布局相冲突
            marginLayoutParams.topMargin = 0
            marginLayoutParams.bottomMargin = 0
            marginLayoutParams.leftMargin = 0
            marginLayoutParams.rightMargin = 0
        }

        //如果当前没有设置重心，就自动获取布局重心
        if (mWindowParams?.gravity == Gravity.NO_GRAVITY) {
            if (layoutParams is FrameLayout.LayoutParams) {
                var gravity: Int = layoutParams.gravity
                if (gravity != FrameLayout.LayoutParams.UNSPECIFIED_GRAVITY) {
                    mWindowParams?.gravity = gravity
                }
            } else if (layoutParams is LinearLayout.LayoutParams) {
                var gravity: Int = layoutParams.gravity
                if (gravity != FrameLayout.LayoutParams.UNSPECIFIED_GRAVITY) {
                    mWindowParams?.gravity = gravity
                }
            }
            if (mWindowParams?.gravity == Gravity.NO_GRAVITY) {
                //默认重心是居中
                mWindowParams?.gravity = Gravity.CENTER
            }
        }
        if (layoutParams != null) {
            if (mWindowParams?.width == WindowManager.LayoutParams.WRAP_CONTENT &&
                mWindowParams?.height == WindowManager.LayoutParams.WRAP_CONTENT
            ) {
                //如果当前 Dialog 的宽高设置了自适应，就以布局中设置的宽高为主
                mWindowParams?.width = layoutParams.width
                mWindowParams?.height = layoutParams.height
            } else {
                // 如果当前通过代码动态设置了宽高，则以动态设置的为主
                layoutParams.width = mWindowParams?.width ?: 0
                layoutParams.height = mWindowParams?.height ?: 0
            }
        }
        update()
        return this as A
    }

    fun showAsDropDown(anchorView: View) {
        showAsDropDown(anchorView, Gravity.BOTTOM)
    }

    fun showAsDropDown(anchorView: View, showGravity: Int) {
        showAsDropDown(anchorView, showGravity, 0, 0)
    }

    /**
     * 将悬浮窗显示在某个 View 下方（和 PopupWindow 同名方法作用类似）
     *
     * @param anchorView            锚点 View
     * @param showGravity           显示重心
     * @param xOff                  水平偏移
     * @param yOff                  垂直偏移
     */
    fun showAsDropDown(anchorView: View, showGravity: Int, xOff: Int, yOff: Int) {
        if (mDecorView?.childCount == 0 || mWindowParams == null) {
            throw IllegalArgumentException("WindowParams and view cannot be empty")
        }
        var _showGravity: Int = 0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            _showGravity = Gravity.getAbsoluteGravity(
                showGravity,
                anchorView.resources.configuration.layoutDirection
            )
        }
        val anchorViewLocation = IntArray(2)
        anchorView.getLocationOnScreen(anchorViewLocation)
        val windowVisibleRect = Rect()
        anchorView.getWindowVisibleDisplayFrame(windowVisibleRect)
        mWindowParams?.gravity = Gravity.TOP or Gravity.START
        mWindowParams?.x = anchorViewLocation[0] - windowVisibleRect.left + xOff
        mWindowParams?.y = anchorViewLocation[1] - windowVisibleRect.top + yOff
        if (showGravity and Gravity.LEFT == Gravity.LEFT) {
            var rootViewWidth: Int = mDecorView?.width ?: 0
            if (rootViewWidth == 0) {
                rootViewWidth = mDecorView?.measuredWidth ?: 0
            }
            if (rootViewWidth == 0) {
                mDecorView?.measure(
                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
                )
                rootViewWidth = mDecorView?.measuredWidth ?: 0
            }
            mWindowParams!!.x -= rootViewWidth
        } else if (showGravity and Gravity.RIGHT == Gravity.RIGHT) {
            mWindowParams!!.x += anchorView.height
        }

        if (showGravity and Gravity.TOP == Gravity.TOP) {
            var rootViewHeight: Int = mDecorView?.height ?: 0
            if (rootViewHeight == 0) {
                rootViewHeight = mDecorView?.measuredHeight ?: 0
            }
            if (rootViewHeight == 0) {
                mDecorView?.measure(
                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
                )
                rootViewHeight = mDecorView?.measuredHeight ?: 0
            }
            mWindowParams!!.y -= rootViewHeight
        } else if (showGravity and Gravity.BOTTOM == Gravity.BOTTOM) {
            mWindowParams!!.y += anchorView.height
        }
        show()
    }

    /**显示悬浮窗*/
    fun show() {
        if (mDecorView?.childCount == 0 || mWindowParams == null) {
            throw IllegalArgumentException("WindowParams and view cannot be empty")
        }
        //如果当前已经显示则进行更新
        if (mShowing) {
            update()
            return
        }
        if (mContext is Activity) {
            if ((mContext as Activity).isFinishing ||
                (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 &&
                        (mContext as Activity).isDestroyed)
            ) {
                return
            }
        }
        try {
            //如果 View 已经被添加的情况下，就先把 View 移除掉
            if (mDecorView?.parent != null) {
                mWindowManager?.removeViewImmediate(mDecorView)
            }
            mWindowManager?.addView(mDecorView, mWindowParams)
            // 当前已经显示
            mShowing = true
            //如果当前限定了显示时长
            if (mDuration != 0) {
                removeCallbacks(this)
                postDelayed(this, mDuration.toLong())
            }
            //注册 Activity 生命周期
            mLifecycle?.register()
            //回调监听
            mListener?.onShow(this)
        } catch (e: Exception) {
            // 如果这个 View 对象被重复添加到 WindowManager 则会抛出异常
            // java.lang.IllegalStateException: View has already been added to the window manager.
            e.printStackTrace()
        }
    }

    /**销毁悬浮窗*/
    fun cancel() {
        if (!mShowing) {
            return
        }
        try {
            //反注册 Activity 生命周期
            mLifecycle?.unregister()
            // 如果当前 WindowManager 没有附加这个 View 则会抛出异常
            // java.lang.IllegalArgumentException: View not attached to window manager
            mWindowManager?.removeViewImmediate(mDecorView)
            // 移除销毁任务
            removeCallbacks(this)
            //回调监听
            mListener?.onDismiss(this)
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            //重置显示状态
            mShowing = false
        }
    }

    /**刷新悬浮窗*/
    fun update() {
        if (!isShowing()) {
            return
        }
        //更新 WindowManger 的显示
        mWindowManager?.updateViewLayout(mDecorView, mWindowParams)
    }

    /**回收释放*/
    fun recycle() {
        if (isShowing()) {
            cancel()
        }
        mListener?.onRecycler(this)
        /**清空所有对象*/
        mListener = null
        mContext = null
        mDecorView = null
        mWindowManager = null
        mWindowParams = null
        mLifecycle = null
    }

    /**当前是否已经显示*/
    fun isShowing(): Boolean {
        return mShowing
    }

    /**获取WindowManager对象*/
    fun getWindowManager(): WindowManager? {
        return mWindowManager
    }

    /**获取WindowManager参数集*/
    fun getWindowParams(): WindowManager.LayoutParams? {
        return mWindowParams
    }

    /**获取上下文*/
    fun getContext(): Context? {
        return mContext
    }

    /**获取根布局*/
    fun getDecorView(): View? {
        return mDecorView
    }

    /**获取内容布局*/
    fun getContentView(): View? {
        if (mDecorView?.childCount == 0) {
            return null
        }
        return mDecorView?.getChildAt(0)
    }

    /**根据ViewId获取View*/
    fun <V : View?> findViewById(id: Int): V? {
        return mDecorView!!.findViewById(id)
    }

    /**设置可见状态*/
    fun setVisibility(id: Int, visibility: Int): A {
        findViewById<View>(id)?.visibility = visibility
        return this as A
    }

    /**设置文本*/
    fun setText(id: Int): A {
        return setText(android.R.id.message, id)
    }

    fun setText(viewId: Int, stringId: Int): A {
        return setText(viewId, mContext?.resources?.getString(stringId))
    }

    fun setText(id: Int, text: CharSequence?): A {
        findViewById<TextView>(id)?.text = text.toString()
        return this as A
    }

    /**设置文本颜色*/
    fun setTextColor(id: Int, color: Int): A {
        findViewById<TextView>(id)?.setTextColor(color)
        return this as A
    }

    /**设置提示*/
    fun setHint(viewId: Int, stringId: Int): A {
        return setHint(viewId, mContext?.resources?.getString(stringId))
    }

    fun setHint(id: Int, text: CharSequence?): A {
        findViewById<TextView>(id)?.hint = text.toString()
        return this as A
    }

    /**设置提示文本颜色*/
    fun setHintColor(id: Int, color: Int): A {
        findViewById<TextView>(id)?.setHintTextColor(color)
        return this as A
    }

    /**设置背景*/
    fun setBackground(viewId: Int, drawableId: Int): A {
        var drawable: Drawable? = null
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            drawable = mContext?.getDrawable(drawableId)
        } else {
            drawable = mContext?.resources?.getDrawable(drawableId)
        }
        return setBackground(viewId, drawable)
    }

    fun setBackground(id: Int, drawable: Drawable?): A {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            findViewById<View>(id)?.background = drawable
        } else {
            findViewById<View>(id)?.setBackgroundDrawable(drawable)
        }
        return this as A
    }

    /**设置图片*/
    fun setImageDrawable(viewId: Int, drawableId: Int): A {
        var drawable: Drawable? = null
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            drawable = mContext?.getDrawable(drawableId)
        } else {
            drawable = mContext?.resources?.getDrawable(drawableId)
        }
        return setImageDrawable(viewId, drawable)
    }

    fun setImageDrawable(viewId: Int, drawable: Drawable?): A {
        findViewById<ImageView>(viewId)?.setImageDrawable(drawable)
        return this as A
    }

    /**获取Handler*/
    fun getHandler(): Handler {
        return HANDLER
    }

    /**延迟执行*/
    fun post(runnable: Runnable): Boolean {
        return postDelayed(runnable, 0)
    }

    /**延迟一段时间执行*/
    fun postDelayed(runnable: Runnable, delayMillis: Long): Boolean {
        if (delayMillis < 0) {
            return false
        }
        return postAtTime(runnable, SystemClock.uptimeMillis() + delayMillis)
    }

    /**在指定的时间执行*/
    fun postAtTime(runnable: Runnable, uptimeMillis: Long): Boolean {
        //发送和这个WindowManager相关的消息回调
        return HANDLER.postAtTime(runnable, this, uptimeMillis)
    }

    /**移除消息*/
    fun removeCallbacks(runnable: Runnable) {
        HANDLER.removeCallbacks(runnable)
    }

    fun removeCallbacksAndMessages() {
        HANDLER.removeCallbacksAndMessages(this)
    }

    /**设置点击事件*/
    fun setOnClickListener(listener: OnClickListener<View>): A {
        return setOnClickListener(mDecorView, listener)
    }

    fun setOnClickListener(id: Int, listener: OnClickListener<View>): A {
        return setOnClickListener(findViewById<View>(id), listener)
    }

    fun setOnClickListener(view: View?, listener: OnClickListener<View>): A {
        // 如果当前是否设置了不可触摸，如果是就擦除掉
        clearWindowFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
        view?.isEnabled = true
        view?.setOnClickListener(ViewClickWrapper(this, listener))
        return this as A
    }

    /**设置长按事件*/
    fun setOnLongClickListener(listener: OnLongClickListener<View>): A {
        return setOnLongClickListener(mDecorView, listener)
    }

    fun setOnLongClickListener(id: Int, listener: OnLongClickListener<View>): A {
        return setOnLongClickListener(findViewById<View>(id), listener)
    }

    fun setOnLongClickListener(view: View?, listener: OnLongClickListener<View>): A {
        //如果当前是否设置了不可触摸，如果是就擦除掉
        clearWindowFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
        view?.isEnabled = true
        view?.setOnLongClickListener(ViewLongClickWrapper(this, listener))
        return this as A
    }

    /**设置触摸事件*/
    fun setOnTouchListener(listener: OnTouchListener<View>): A {
        return setOnTouchListener(mDecorView, listener)
    }

    fun setOnTouchListener(id: Int, listener: OnTouchListener<View>): A {
        return setOnTouchListener(findViewById<View>(id), listener)
    }

    private fun setOnTouchListener(view: View?, listener: OnTouchListener<View>): A {
        clearWindowFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
        view?.isEnabled = true
        view?.setOnTouchListener(ViewTouchWrapper(this, listener))
        return this as A
    }

    override fun run() {
        cancel()
    }

    /**View的点击事件监听*/
    interface OnClickListener<V : View> {
        fun onClick(toast: AndroidToast<*>, view: V)
    }

    /**View的长按事件监听*/
    interface OnLongClickListener<V : View> {
        fun onLongClick(toast: AndroidToast<*>, view: V): Boolean
    }

    /**View的触摸事件监听*/
    interface OnTouchListener<V : View> {
        fun onTouch(toast: AndroidToast<*>, view: V, event: MotionEvent): Boolean
    }

    /**Toast 生命周期*/
    interface OnLifecycle {
        /**显示回调*/
        fun onShow(toast: AndroidToast<*>) {}

        /**消失回调*/
        fun onDismiss(toast: AndroidToast<*>) {}

        /**回收回调*/
        fun onRecycler(toast: AndroidToast<*>) {}
    }
}
